package com.whw.fy.service.impl;

import com.whw.fy.config.AccessTokenService;
import com.whw.fy.entity.*;
import com.whw.fy.mapper.*;
import com.whw.fy.utils.SendMessageUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

import com.whw.fy.service.AttendanceStuService;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


@Service
public class AttendanceStuServiceImpl implements AttendanceStuService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private AttendanceStuMapper attendanceStuMapper;
    @Resource
    private ClazzMapper clazzMapper;
    @Resource
    private StudentMapper studentMapper;
    @Resource
    private PurchaseCourseRecordsMapper purchaseCourseRecordsMapper;
    @Resource
    private LessonMapper lessonMapper;
    @Resource
    private StaffMapper staffMapper;
    @Resource
    private AccessTokenService accessTokenService;
    @Resource
    private MessageboxMapper messageboxMapper;
    @Resource
    private ScheduleMapper scheduleMapper;

    @Override
    public Message deleteByPrimaryKey(Integer attStuId) {
        return attendanceStuMapper.deleteByPrimaryKey(attStuId) > 0 ? Message.success(null) : Message.fail(null);
    }

    @Override
    public Message insert(AttendanceStu record) {
        return attendanceStuMapper.insert(record) > 0 ? Message.success(null) : Message.fail(null);
    }

    @Override
    public Message insertSelective(AttendanceStu record) {
        record.setCompletionTimes(clazzMapper.selectByPrimaryKey(record.getClassId()).getClassCompletionTimes() + 1);
        record.setPostTime(new Date());
        return attendanceStuMapper.insertSelective(record) > 0 ? Message.success(null) : Message.fail(null);
    }

    @Override
    public Message selectByPrimaryKey(Integer attStuId) {
        return Message.success(null).add(attendanceStuMapper.selectByPrimaryKey(attStuId));
    }

    @Override
    public Message updateByPrimaryKeySelective(AttendanceStu record) {
        return attendanceStuMapper.updateByPrimaryKeySelective(record) > 0 ? Message.success(null) : Message.fail(null);
    }

    @Override
    public Message updateByPrimaryKey(AttendanceStu record) {
        return attendanceStuMapper.updateByPrimaryKey(record) > 0 ? Message.success(null) : Message.fail(null);
    }

    @Override
    //事务注解
    @Transactional
    public Message batchInsert(int classId, List<AttendanceStu> list) {
        Date date = new Date();
        for (AttendanceStu attendanceStu : list) {
            attendanceStu.setPostTime(date);
        }
        if (signInSuccessList(list))
            return attendanceStuMapper.batchInsert(list) > 0 ? Message.success(null) : Message.fail(null);
        else return Message.fail("学生签到后续操作失败请联系管理员");
    }

    @Override
    public Message selectAll() {
        return Message.success(null).add(attendanceStuMapper.selectAll());
    }


    @Override
    public Message selectStudentByClassIDAndCompletionTimesAdmin(int classId, int CompletionTimes) {
        return Message.success(null).add(attendanceStuMapper.selectByClassIDAndCompletionTimes(classId, CompletionTimes));
    }

    @Override
    public Message selectStudentByClassIDAndCompletionTimes(int classId, int CompletionTimes) {
        int studentAttendNumber = 0;
        int studentSumNumber = 0;
        int studentAbsenseNumber = 0;
        List<AttendanceStu> attendanceStuList = attendanceStuMapper.selectByClassIDAndCompletionTimes(classId, CompletionTimes);
        List<Map> studentList = new LinkedList<>();
        for (AttendanceStu attendanceStu : attendanceStuList) {
            Student student = studentMapper.selectByPrimaryKey(attendanceStu.getStudentId());
            HashMap map = new HashMap();
            map.put("student", student);
            map.put("attendance", attendanceStu.getAttendance());
            studentList.add(map);
            studentSumNumber = studentSumNumber + 1;
            if (attendanceStu.getAttendance() == 1) {
                studentAttendNumber = studentAttendNumber + 1;
            } else {
                studentAbsenseNumber = studentAbsenseNumber + 1;
            }
        }
        HashMap map = new HashMap();
        map.put("studentAttendNumber", studentAttendNumber);
        map.put("studentSumNumber", studentSumNumber);
        map.put("studentAbsenseNumber", studentAbsenseNumber);
        map.put("studentList", studentList);
        return Message.success(null).add(map);
    }

    @Override
    public Message selectByStudentIdAndAttendance(int studentId, int attendance) {
        return Message.success(null).add(attendanceStuMapper.selectByStudentIdAndAttendance(studentId, attendance));
    }

    @Override
    public Message selectByStudentId(int studentId) {
        return Message.success(null).add(attendanceStuMapper.selectByStudentId(studentId));
    }


    /**
     * 此方法为完成学生签到后的一系列操作
     * 包括：
     * 修改排课状态
     * 修改课程上课次数
     * 修改学生已购买课程记录中的已上课次数和剩余次数
     * 检测剩余课程数量是否达到阈值
     * 如果达到了阈值，发出微信通知和管理端通知，同时向老师、家长、财务发出续费通知
     * 修改排课状态未完成！！！！！！！！！！！
     */
    @Transactional
    public synchronized boolean signInSuccessList(List<AttendanceStu> attendanceStuList) {
        //修改课程上课次数事件
        //拿到第一条数据
        AttendanceStu attendanceStu0 = attendanceStuList.get(0);
        int classId = attendanceStu0.getClassId();
        Clazz clazz = clazzMapper.selectByPrimaryKey(classId);
        int lessonId = clazz.getClassCourseId();
        //修改上课次数由小程序完成，小程序需要执行进行+1操作
        int classCompletionTimes = attendanceStu0.getCompletionTimes();
        if (updateScheduleStatus(classId, classCompletionTimes) == false) {
            logger.info("修改排课状态的结果,是失败！");
            return false;
        } else {
            logger.info("修改排课状态的结果,是成功！");
        }

        //修改课程上课次数的结果
        int rs1 = clazzMapper.updateClassCompletionTimesByClassId(classCompletionTimes, classId);
        logger.info("修改课程上课次数的结果,是{{}}", rs1);

        //修改学生已购买课程记录中的已上课次数和剩余次数事件,检测剩余课程数量是否达到阈值
        for (AttendanceStu attendanceStu : attendanceStuList) {
            int studentId = attendanceStu.getStudentId();
            //查询学生购买该课程数量
            PurchaseCourseRecords record = purchaseCourseRecordsMapper.selectByStudentIdAndLessonId(studentId, lessonId);
            int PurchaseClassTimes = record.getClassTimes();
            int PurchaseRemainingTimes = record.getRemainingTimes();
            int PurchaseRemindTimes = record.getRemindTimes();
            if (PurchaseRemainingTimes == 0) {
                logger.info("学生id：{{}}，姓名：{{}}已欠费！请及时缴费！", record.getStudent().getStudentId(), record.getStudent().getStudentName());
                if (arrearageReminder(record) == false)
                    return false;
            } else {
                int rs2 = purchaseCourseRecordsMapper.updateClassTimesAndRemainingTimesByPurchaseId(PurchaseClassTimes + 1, PurchaseRemainingTimes - 1, record.getPurchaseId());
                logger.info("修改学生已购买课程记录中的已上课次数和剩余次数的结果,是{{}}", rs2);
            }
            //检测剩余课程数量是否达到阈值
            int panduan = PurchaseRemainingTimes - 1;
            if (panduan <= PurchaseRemindTimes) {
                if (renewalReminder(record, attendanceStu) == false)
                    return false;

            }
        }


        return true;
    }

    /**
     * 欠费通知功能
     * 尚未完善
     * 需要wxy完善
     */
    @Transactional
    public synchronized boolean arrearageReminder(PurchaseCourseRecords records) {
        return true;
    }

    /**
     * 该方法为课程剩余数量达到阈值需要发出微信通知和管理端通知，同时向老师、家长、财务发出续费通知
     * 尚未完善
     * 需要wxy完善
     */
    @Transactional
    public synchronized boolean renewalReminder(PurchaseCourseRecords records, AttendanceStu attendanceStu) {


        //微信小程序通知教师
        String studentName = studentMapper.selectByPrimaryKey(records.getStudentId()).getStudentName();
        String lessonName = lessonMapper.selectByPrimaryKey(records.getLessonId()).getLessonName();
        Staff staff = staffMapper.selectByPrimaryKey(attendanceStu.getTeacherId());
        String teacherName = staff.getStaffName();
        String openId = staff.getStaffOpenid();
        String rs1 = SendMessageUtil.sendRenewalReminderMessage(studentName, lessonName, teacherName, records.getRemainingTimes(), openId, accessTokenService.getAccessToken());
        logger.info("向老师发出续费微信通知:{}", rs1);

        //通过消息盒子在管理端通知财务 财务权限4
        List<Staff> caiwuList = staffMapper.selectAllByStaffJurisdiction(4);
        Date postTime = new Date();
        List<Messagebox> messageboxList = new LinkedList<>();
        for (Staff caiwu : caiwuList) {
            Messagebox messagebox = new Messagebox();
            messagebox.setMessageboxPostUserId(-1);
            messagebox.setMessageboxReceiveUserId(caiwu.getStaffId());
            messagebox.setMessageboxPostTime(postTime);
            messagebox.setMessageboxStatus(0);
            messagebox.setMessageboxTitle("学生续费提醒");
            messagebox.setMessageboxContent("学生：" + studentName + "，课程：" + lessonName + "，剩余" + records.getRemainingTimes() + "次课，需要续费！");
            messageboxList.add(messagebox);
        }
        int rs2 = messageboxMapper.batchInsert(messageboxList);
        logger.info("向所有财务发出学生续费管理端消息通知:{}", rs2);
        return true;
    }

    @Transactional
    public synchronized boolean updateScheduleStatus(int classId, int classCompletionTimes) {
        List<Schedule> scheduleList = scheduleMapper.selectByClassIdAndNowOrderByTimeSkcdAsc(classId);
        if (scheduleList.size() > 0) {
            for (Schedule schedule : scheduleList) {
                if (schedule.getScheduleStatus() == 0) {
                    return scheduleMapper.updateScheduleStatusAndScheduleCompletionTimesByScheduleId(1, classCompletionTimes, schedule.getScheduleId()) > 0 ? true : false;
                }
            }
        } else return false;
        return false;
    }

    @Override
    public int batchInsert(List<AttendanceStu> list) {
        return attendanceStuMapper.batchInsert(list);
    }

    @Override
    public Message selectAllByStudentIdAndCompletionTimesAndClassId(Integer studentId, Integer completionTimes, Integer classId) {
        return Message.success(null).add(attendanceStuMapper.selectAllByStudentIdAndCompletionTimesAndClassId(studentId, completionTimes, classId));
    }

    @Override
    public int updateBatch(List<AttendanceStu> list) {
        return attendanceStuMapper.updateBatch(list);
    }

    @Override
    public int updateBatchSelective(List<AttendanceStu> list) {
        return attendanceStuMapper.updateBatchSelective(list);
    }
}





